package rolesystem.agentlogic.GUI;

import java.awt.*;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

import rolesystem.agentlogic.managers.EnvironmentManager;
import rolesystem.agentlogic.utilityclasses.AgentMap;
import rolesystem.agentlogic.utilityclasses.Square;

public class EnvVisualizer extends Canvas
{
	  /**
	 * 
	 */
		private static final long serialVersionUID = 3111297938794921923L;
	private static Image offScreenImage;
	  private Graphics offScreenGraphics;
	  private static Image offScreenImageDrawed;
	  
	  private Graphics offScreenGraphicsDrawed;
	  
	  private static int cellSize;
	  private static Dimension dim;
	  private static ArrayList<Square>[][] env;
	  
	  private static ArrayList<AgentMap> agents;
	  
	  private static Semaphore semaphore;
	  private static Semaphore semaphoreUp;
	  
	  
	  public EnvVisualizer( int cellSize_p, int dim_x,int dim_y) 
	  {
		    cellSize = cellSize_p;

		    setBackground(new Color(0x999999));
		    dim = new Dimension( dim_x, dim_y);
		    
		    agents= new ArrayList<AgentMap>();
		    
		    EnvVisualizer.semaphore = new Semaphore(1);
		    EnvVisualizer.semaphoreUp = new Semaphore(1); 
	  }
	  
	  public static void updateObj(ArrayList<Square>[][] env_p) 
	  {
		  env=env_p;
	  }
	  
	  public static void updateAgent(AgentMap updatedAgent) 
	  {
		  semaphore.acquireUninterruptibly();
		  
		  boolean agentfound=false; 
		  
		  for(int i=0;i<agents.size();i++)
		  {
			  if(agents.get(i).id==updatedAgent.id)
			  {
				agentfound=true;
				agents.set(i,updatedAgent);		
				break;
			  }
		  }  
		  
		  if(agentfound==false)
		  {
			  agents.add(updatedAgent); 
		  }  
		  
		  semaphore.release();
	  }
	  
	  /** 
	   * Use double buffering.
	   * @see java.awt.Component#update(java.awt.Graphics)
	   */
	  public void update(Graphics g) 
	  {
		semaphoreUp.acquireUninterruptibly();
		  
		Dimension d = getSize();
	    
	    if ((offScreenImage == null)) 
	    {
	      offScreenImage = createImage(d.width, d.height);
	      offScreenGraphics = offScreenImage.getGraphics();
	    }
	    
	    paint(offScreenGraphics);
	    g.drawImage(offScreenImage, 0, 0, null);
	    
	    semaphoreUp.release();
	  }
	  
	  public void paint(Graphics g) 
	  {
		  semaphore.acquireUninterruptibly();  
		  
		  // Draw grid on background image, which is faster
		    if (offScreenImageDrawed == null) 
		    {
		      Dimension d = getSize();
		      
		      offScreenImageDrawed = createImage(d.width, d.height);
		      offScreenGraphicsDrawed = offScreenImageDrawed.getGraphics();
		      
		      // draw background
		      offScreenGraphicsDrawed.setColor(getBackground());
		      offScreenGraphicsDrawed.fillRect(0, 0, d.width, d.height);
		      offScreenGraphicsDrawed.setColor(Color.gray);
		      offScreenGraphicsDrawed.fillRect(0, 0, cellSize * dim.width - 1, cellSize * dim.height - 1);
		      offScreenGraphicsDrawed.setColor(getBackground());
		      
		      for (int x = 1; x < dim.width; x++) 
		      {
		        offScreenGraphicsDrawed.drawLine(x * cellSize - 1, 0, x * cellSize - 1, cellSize * dim.height - 1);
		      }
		      for (int y = 1; y < dim.height; y++) 
		      {
		        offScreenGraphicsDrawed.drawLine( 0, y * cellSize - 1, cellSize * dim.width - 1, y * cellSize - 1);
		      }
		      
		    }
		    g.drawImage(offScreenImageDrawed, 0, 0, null);
		    
		    // draw objects
		    g.setColor(Color.yellow);
		    
			for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
			{
				for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
				{
					if(env[i][j].get(0).getWeight()!=0)
				    {   
						g.fillRect(i * cellSize, j * cellSize, cellSize - 1, cellSize - 1); 
				    }
				}    
			}
			
			// draw obstacles
			g.setColor(Color.green);
		    
			for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
			{
				for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
				{
					if(env[i][j].get(0).getBlocked()==true)
				    {   
						g.fillRect(i * cellSize, j * cellSize, cellSize - 1, cellSize - 1); 
				    }
				}    
			}
			
			// Draw Nest
			g.setColor(Color.red);
			g.fillRect(1 * cellSize, 1 * cellSize, cellSize - 1, cellSize - 1);
			
			
			//Draw Agents
			g.setColor(Color.black);
			
			for(int i=0;i<agents.size();i++)
			  {
				g.setColor(Color.black);
				g.fillRect(agents.get(i).position_agent.pos_x  * cellSize, agents.get(i).position_agent.pos_y * cellSize, cellSize - 1, cellSize - 1); 
			    
				g.setFont(new Font("SanSerif", Font.PLAIN, 13));
				g.setColor(Color.red);
			    FontMetrics fm = g.getFontMetrics();
			    int w = fm.stringWidth(String.valueOf(agents.get(i).id));
			    int h = fm.getAscent();
			    g.drawString(String.valueOf(agents.get(i).id), (agents.get(i).position_agent.pos_x  * cellSize)+(w*2/3), (agents.get(i).position_agent.pos_y  * cellSize)+ h*(4/3) );
			  }  
			
			semaphore.release();

		  }
	  
	  
	
	
	
}
